package case26

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"regexp"
	"strings"
)

func Test() {

	fmt.Println("🎯示例二十六：自定义验证器-使用中间件进行字段校验")

	r := gin.Default()

	queryValidators := map[string]func(string) error{
		"username": validUsername,
		"password": validPassword,
		"email": func(email string) error {
			if !strings.Contains(email, "@") {
				return fmt.Errorf("邮箱格式不正确")
			}
			return nil
		},
	}

	// Login
	r.GET("/login", ValidateQueryParams(queryValidators), func(c *gin.Context) {

		c.JSON(http.StatusOK, gin.H{
			"message": "所有参数验证通过",
		})
	})

	r.Run(":60000")

}

// 中间件方式校验单个字段
func ValidateQueryParams(validators map[string]func(string) error) gin.HandlerFunc {
	return func(c *gin.Context) {
		errors := make(map[string]string)

		for param, validatorFunc := range validators {
			value := c.Query(param)
			if err := validatorFunc(value); err != nil {
				errors[param] = err.Error()
			}
		}

		if len(errors) > 0 {
			c.JSON(http.StatusBadRequest, gin.H{
				"errors": errors,
			})
			c.Abort()
			return
		}

		c.Next()
	}
}

// username 验证器
func validUsername(username string) error {
	if username == "" || len(username) == 0 {
		return fmt.Errorf("username is not null.")
	}

	return nil
}

// password 验证器
func validPassword(password string) error {
	if len(password) < 6 {
		return fmt.Errorf("password 不能小于6位.")
	}

	// 修复后的正则：必须同时包含数字和字母，并且匹配整个字符串
	hasDigit := regexp.MustCompile(`[0-9]`).MatchString(password)
	hasLetter := regexp.MustCompile(`[a-zA-Z]`).MatchString(password)

	if !hasDigit || !hasLetter {
		return fmt.Errorf("password 必须包含字母和数字")
	}
	return nil
}
